package com.yearner.reviewplan.plan;

import apijson.RequestMethod;
import apijson.framework.APIJSONConstant;
import apijson.orm.Parser;
import com.yearner.reviewplan.apijson.APIJSONParser;
import com.yearner.reviewplan.apijson.DemoParser;
import com.yearner.reviewplan.common.aspect.AuthTokenV1;
import com.yearner.reviewplan.common.aspect.WebLog;
import com.yearner.reviewplan.common.enums.Consts;
import com.yearner.reviewplan.common.model.Result;
import com.yearner.reviewplan.plan.commands.*;
import com.yearner.reviewplan.plan.model.Plan;
import com.yearner.reviewplan.plan.model.PlanId;
import com.yearner.reviewplan.plan.model.PlanVo;
import com.yearner.reviewplan.plan.model.ReviewDto;
import com.yearner.reviewplan.user.data.Identification;
import com.yearner.reviewplan.user.model.User;
import com.yearner.reviewplan.user.model.UserId;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

import static apijson.RequestMethod.GET;
import static apijson.RequestMethod.GETS;


/**
 * @author pengyg
 * @since 2019/10/18
 */
@Api
@RestController
@RequestMapping("/api/plan")
public class PlanController {
    private static final Logger log = LoggerFactory.getLogger(PlanController.class);

    private final PlanApplicationService applicationService;
    private final PlanRepresentation representation;
    private final Identification identification;
    @Autowired
    public PlanController(PlanApplicationService applicationService, PlanRepresentation representation, Identification identification) {
        this.applicationService = applicationService;
        this.representation = representation;
        this.identification = identification;
    }

    @AuthTokenV1
    @PostMapping("newPlan")
    public Result<String> newPlan(@RequestBody CreatePlanCommand command,HttpServletRequest request) {
        if (!identification.authUserId(command.getUserId(),request)) {
            command.setUserId(request.getAttribute(Consts.CURRENT_USER_ID).toString());
        }
        applicationService.newPlan(command);
        return Result.success("新建复习计划成功");
    }

    @AuthTokenV1
    @PostMapping("updatePlan")
    public Result<String> updatePlan(@RequestBody UpdatePlanCommand command,HttpServletRequest request) {
        // 传递的id不为空，验证失败就报错
        if (!identification.authUserId(command.getUserId(),request)) {
            command.setUserId(request.getAttribute(Consts.CURRENT_USER_ID).toString());
        }
        applicationService.updatePlan(command);
        return Result.success("更新成功");
    }

    @WebLog
    @AuthTokenV1
    @PostMapping(value = "finish")
    public Result<String> finish(@RequestBody FinishPlanCommand command,HttpServletRequest request) {
        String userId = request.getAttribute(Consts.CURRENT_USER_ID).toString();
        applicationService.finishThisTime(userId, command);
        return Result.success();
    }
    @AuthTokenV1
    @PostMapping("/get")
    public Result<String> get(@RequestBody String requestJson,HttpServletRequest request) {
        String userId = request.getAttribute(Consts.CURRENT_USER_ID).toString();
        User user = identification.getUserById(userId);
        HttpSession session = request.getSession();
        session.setAttribute(APIJSONConstant.VISITOR_,user);
        return Result.success("ok",getParse(requestJson, session));
    }

    /**
     * 获取所有需要进行复习的计划
     * @param request HttpServletRequest
     * @return
     */
    @AuthTokenV1
    @GetMapping("needReviews")
    public Result<List<PlanVo>> needReviews(HttpServletRequest request) {
        String userId = request.getAttribute(Consts.CURRENT_USER_ID).toString();
        User user = identification.getUserById(userId);
        List<ReviewDto> reviewDtoList = representation.getReviewDtoByUserId(userId);
        List<PlanVo> need = representation.getNeedReview(reviewDtoList, user.getCycle());
        return Result.success(need);
    }

    /**
     *
     * @param request HttpServletRequest 持有userId
     * @return
     */
    @GetMapping(value = "getAllPlans")
    @AuthTokenV1
    public Result<List<PlanVo>> getAllPlans(HttpServletRequest request) {
        String userId = request.getAttribute(Consts.CURRENT_USER_ID).toString();
        List<Plan> all = representation.getByUserId(userId);
        List<PlanVo> voList = new ArrayList<>();
        for (Plan p : all) {
            voList.add(new PlanVo(p));
        }
        return Result.success(voList);
    }
    @GetMapping(value = "info")
    @AuthTokenV1
    public Result<PlanVo> info(GetPlanInfoCommand command, HttpServletRequest request) {
        UserId userId = UserId.byId(request.getAttribute(Consts.CURRENT_USER_ID).toString());
        List<Plan> plans = representation.getByPlanId(userId, PlanId.of(command.getPlanId()));
        if(plans.isEmpty()){
            Result.error("用户id不匹配");
        }
        return Result.success(new PlanVo(plans.get(0)));
    }

    /**
     * 删除指定复习计划
     * @param command DeletePlanCommand
     * @return
     */
    @DeleteMapping(value = "deletePlan")
    @AuthTokenV1
    public Result<String> deletePlan(@RequestBody DeletePlanCommand command,HttpServletRequest request) {
        if (!identification.authUserId(command.getUserId(),request)) {
            command.setUserId(request.getAttribute(Consts.CURRENT_USER_ID).toString());
        }
        applicationService.deletePlan(command.getUserId(), command.getPlanId());
        return Result.success();
    }

//    @GetMapping(value = "searchPlan")
//    @AuthTokenV1
//    public Result<List<PlanVo>> searchPlan(SearchPlanCommand command,HttpServletRequest request) {
//        String userId = request.getAttribute(Consts.CURRENT_USER_ID).toString();
//        List<Plan> result = applicationService.search(userId, command);
//        List<PlanVo> voList = new ArrayList<>();
//        return Result.success(voList);
//    }
public Parser<String> newParser(HttpSession session, apijson.RequestMethod method) {
    APIJSONParser parser = new DemoParser();
    parser.setMethod(method);
    parser.setSession(session);
    return parser;
}

    public String parse(String request, HttpSession session, apijson.RequestMethod method) {
        return newParser(session, method).parse(request);
    }

    //通用接口，非事务型操作 和 简单事务型操作 都可通过这些接口自动化实现<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    /**获取
     * @param request 只用String，避免encode后未decode
     * @param session
     * @return
     * @see {@link RequestMethod#GET}
     */
    public String getParse(String request, HttpSession session) {
        return parse(request, session, GET);
    }
}
